package com.dwxt.cms.service;

import com.dwxt.cms.dao.MenuMapper;
import com.dwxt.cms.dao.RoleMapper;
import com.dwxt.cms.dao.RoleMenuMapper;
import com.dwxt.cms.dao.RolePermissionMapper;
import com.dwxt.cms.entity.*;
import com.dwxt.cms.entity.dto.RoleDTO;
import com.dwxt.cms.entity.vo.RoleVO;
import com.dwxt.common.base.BaseResult;
import com.dwxt.common.base.StatusCode;
import com.dwxt.common.util.JsonUtils;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class RoleServiceAdmin {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Autowired
    private PermissionServiceAdmin permissionServiceAdmin;

    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    @Autowired
    private MenuMapper menuMapper;

    @Transactional
    public BaseResult createOrUpdateRole(RoleDTO roleDTO) {
        if (roleDTO.getMenuIds() == null) {
            return BaseResult.build(StatusCode.MENU_NOT_EXIST);
        }
        if (roleDTO.getId() == null) {
            Role role = selectByName(roleDTO.getName());
            if (role == null) {
                role = new Role();
                role.setName(roleDTO.getName());
                int i = roleMapper.insertSelective(role);
                Integer roleId = role.getId();
                //批量插入角色菜单记录
                batchInsertRoleMenu(roleDTO.getMenuIds(), roleId);
                //批量插入角色权限记录
                List<Permission> permissions = permissionServiceAdmin.selectByCategoryList(roleDTO.getCategoryList());
                batchInsertRolePermission(roleId, permissions);
                return BaseResult.ok();
            } else {
                return BaseResult.build(StatusCode.ROLE_NAME_EXIST);
            }
        } else {
            roleMapper.updateByPrimaryKeySelective(roleDTO);
            //删除原有的roleMenu
            RoleMenuExample roleMenuExample = new RoleMenuExample();
            Integer roleId = roleDTO.getId();
            roleMenuExample.createCriteria().andRoleIdEqualTo(roleId);
            roleMenuMapper.deleteByExample(roleMenuExample);
            //批量插入角色菜单记录
            List<Integer> menuIds = roleDTO.getMenuIds();
            batchInsertRoleMenu(menuIds, roleId);

            //删除原有的rolePermission
            RolePermissionExample rolePermissionExample = new RolePermissionExample();
            rolePermissionExample.createCriteria().andRoleIdEqualTo(roleId);
            rolePermissionMapper.deleteByExample(rolePermissionExample);
            //批量插入角色权限记录
            List<Permission> permissions = permissionServiceAdmin.selectByCategoryList(roleDTO.getCategoryList());
            batchInsertRolePermission(roleId, permissions);
            return BaseResult.ok();
        }
    }

    private void batchInsertRolePermission(Integer roleId, List<Permission> permissions) {
        List<RolePermission> rolePermissions = permissions.stream().map(Permission::getId).map(permissionId -> {
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(permissionId);
            return rolePermission;
        }).collect(Collectors.toList());
        rolePermissionMapper.batchInsert(rolePermissions);
    }

    private void batchInsertRoleMenu(List<Integer> id, Integer roleId) {
        List<RoleMenu> roleMenus = id.stream().map(menuId -> {
            RoleMenu roleMenu = new RoleMenu();
            roleMenu.setMenuId(menuId);
            roleMenu.setRoleId(roleId);
            return roleMenu;
        }).collect(Collectors.toList());
        roleMenuMapper.batchInsert(roleMenus);
    }

    public Role selectByName(String name) {
        RoleExample example = new RoleExample();
        example.createCriteria().andNameEqualTo(name);
        List<Role> roles = roleMapper.selectByExample(example);
        return roles.isEmpty() ? null : roles.get(0);
    }

    @Transactional
    public int deleteByPrimaryKey(Integer id) {
        return roleMapper.deleteByPrimaryKey(id);
    }


    public BaseResult selectAllRoleVo() {
        List<Role> roleVOS = new ArrayList<>();

        RoleExample example = new RoleExample();
        List<Role> roleList = roleMapper.selectByExample(example);
        PageInfo<Role> pageInfo = new PageInfo<>(roleList);
        for (Role role : roleList) {
            RoleVO roleVo = JsonUtils.jsonToPojo(JsonUtils.objectToJson(role), RoleVO.class);
            Integer roleId = roleVo.getId();
            List<String> category = permissionServiceAdmin.selectDistinctCategoryByRoleId(roleId);
            roleVo.setCategory(category);

            RoleMenuExample roleMenuExample = new RoleMenuExample();
            roleMenuExample.createCriteria().andRoleIdEqualTo(roleId);
            List<RoleMenu> roleMenus = roleMenuMapper.selectByExample(roleMenuExample);
            List<Integer> collect = roleMenus.stream().map(roleMenu -> {
                return roleMenu.getMenuId();
            }).collect(Collectors.toList());
            List<Menu> menus = new ArrayList<>();
            if (collect.size() != 0) {
                MenuExample menuExample = new MenuExample();
                menuExample.createCriteria().andIdIn(collect);
                menus = menuMapper.selectByExample(menuExample);
            }
            roleVo.setMenus(menus);
            roleVOS.add(roleVo);
        }
        pageInfo.setList(roleVOS);
        return BaseResult.ok(pageInfo);
    }


    public List<Role> selectAllRole() {
        RoleExample example = new RoleExample();
        return roleMapper.selectByExample(example);
    }

}
